home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1997 April
/
EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso
/
EARCD
/
text
/
hyper
/
hsc_source.lha
/
hsc
/
source
/
ugly
/
fname.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-11-12
|
12KB
|
501 lines
/*
* fname.c
*
* filename processing functions
*
* Copyright (C) 1994,95,96 Thomas Aglassinger
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* updated: 27-Oct-1996
* created: 24-May-1994
*
*-------------------------------------------------------------------
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "utypes.h"
#include "umemory.h"
#include "ustring.h"
#include "expstr.h"
#define NOEXTERN_UGLY_FNAME_H
#include "fname.h"
/*
* get_fext
*
* get filename extension
*
* params: fn...full filename to examine
* result: extension of _fn or NULL, if fn was also NULL
*
*/
BOOL get_fext(EXPSTR * dest, CONSTRPTR fn)
{
CONSTRPTR fn_ext = fn; /* result var */
/* search for end of string */
while (fn_ext[0])
fn_ext++;
/* search string backwards for "." or PATH_SEPARATOR */
do
/* nufin */ ;
while ((fn_ext != fn) /* beginning of name reached? */
&& (fn_ext--) /* process next char */
&& (fn_ext[0] != '.')
&& (strchr(PATH_SEPARATOR, fn_ext[0]) == NULL));
/* copy extension to dest */
if (fn_ext[0] == '.')
set_estr(dest, ++fn_ext);
else
clr_estr(dest);
return (ok_fnl_fext(dest));
}
/*
* get_fname
*
*
*/
BOOL get_fname(EXPSTR * dest, CONSTRPTR fn)
{
CONSTRPTR fn_name = fn;
fn_name = ustrrpbrk(fn_name, PATH_SEPARATOR);
/* copy extension to dest */
if (fn_name)
set_estr(dest, ++fn_name);
else
set_estr(dest, fn);
return (ok_fnl_fname(dest));
}
/*
* get_fpath
*
*
*/
BOOL get_fpath(EXPSTR * dest, CONSTRPTR fn)
{
STRPTR pa_name = ustrrpbrk(fn, PATH_SEPARATOR);
if (pa_name)
{
set_estrn(dest, fn, strlen(fn) - strlen(pa_name) + 1);
}
else
clr_estr(dest);
return (ok_fnl_fpath(dest));
}
/*
* get_fsdir: get next subdirectory (including separator)
*
*/
BOOL get_fsdir(EXPSTR * dest, CONSTRPTR fn)
{
STRPTR fn_name = strpbrk(fn, PATH_SEPARATOR);
if (fn_name)
{
set_estrn(dest, fn, strlen(fn) - strlen(fn_name) + 1);
}
else
clr_estr(dest);
return (ok_fnl_fpath(dest));
}
/*
* get_fdrive
*
*
*/
BOOL get_fdrive(EXPSTR * dest, CONSTRPTR fn)
{
set_estr(dest, fn); /* dummy data */
clr_estr(dest);
return (ok_fnl_fpath(dest));
}
/*
* fextidx: get filename extension index of string
*
* params: fn...filename to examine
* result: index in _fn, where extension starts
*
* NOTE: if _fn has an extension at all, _fn[i] is equal to '.', else
* _fn has no extension (e.g. "TESTFILE") and _fn[i] is equal
* to '\0'.
*
* (internal function)
*
*/
static size_t fextidx(CONSTRPTR fn)
{
size_t i; /* string index counter */
i = strlen(fn) - 1; /* scan string backwards... */
while ((i) && (fn[i] != '.')
&& (strchr(PATH_SEPARATOR, fn[i]) == NULL))
i--;
if (fn[i] != '.')
i = strlen(fn);
return i; /* return result */
}
/*
* clr_fext: clear filename extension
*
* params: dest...string that contains filename to strip
*
* EXAMPLE: "testfile.txt" -> "testfile"
*
*/
BOOL clr_fext(EXPSTR * dest)
{
BOOL ok;
size_t extidx = fextidx(estr2str(dest));
/* index, where extension starts */
ok = set_estrn(dest, estr2str(dest), extidx);
ok &= ok_fnl_fpath(dest);
return (ok);
}
/*
* set_fext: set new (last) extension for filename
*
* params: dest....string that contains old filename
* newext..new extension to set
*
* EXAMPLE: "testfile.txt", "lha" -> "testfile.lha"
* "hugo.tar.gz" , "lha" -> "hugo.tar.lha"
*/
BOOL set_fext(EXPSTR * dest, CONSTRPTR newext)
{
BOOL ok;
ok = clr_fext(dest);
ok &= app_estrch(dest, '.');
ok &= app_estr(dest, newext);
ok &= ok_fnl_fpath(dest);
return (ok);
}
/*
* app_fext: append extension to filename
*
* EXAMPLE: ("testfile.txt", "lha") -> "testfile.txt.lha"
* -> "testfile.lha" (msdos)
*/
BOOL app_fext(EXPSTR * dest, CONSTRPTR newext)
{
BOOL ok = app_estrch(dest, '.');
ok &= app_estr(dest, newext);
ok &= ok_fnl_fpath(dest);
return (ok);
}
/*
* set_fextIdx: set file name index extension
*
* params: dest..destination string with new extension
* fn....source string with extension to replace
* idx...extension index
*/
BOOL set_fnameIdx(EXPSTR * dest, int idx)
{
char fn_ext[12]; /* index extension */
sprintf(fn_ext, "%03d", idx); /* create index string */
return (set_fext(dest, fn_ext));
}
/*
* link_fname: link directory and filename together
*
* params: dest..where to store result
* dir...directoryname
* fn....filename to append
*
* NOTE: a PATHSEPARATOR[0] is append to dir, if none exists
* NOTE: dir and fn MUST NOT be part of dest,
* when invoking this funtion
*/
BOOL link_fname(EXPSTR * dest, STRPTR dir, STRPTR fn)
{
BOOL anydir; /* TRUE, if any dir passed as arg */
BOOL ok = TRUE;
/* is a dir passed? */
anydir = (dir != NULL);
if (anydir)
anydir = (strlen(dir) != 0);
if (anydir)
{
/* clone dir, if any
*
* NOTE: it's neccesarry to work with a copy do `dir',
* because if `dir' is part or `dest', this could lead
* to a mungwall hit */
STRPTR dir_clone = strclone(dir); /* clone of `dir' */
set_estr(dest, dir_clone);
/* check, if the last char of dir is a path separator */
/* ->if not, append a direcory separator */
if (!strchr(PATH_SEPARATOR, dir_clone[strlen(dir_clone) - 1]))
app_estrch(dest, DIR_SEPARATOR);
/* free cloned dir */
ufreestr(dir_clone);
}
else
clr_estr(dest);
/* append filename */
if (fn)
app_estr(dest, fn);
ok &= ok_fnl_fpath(dest);
return ok;
}
/*
* link_envfname: link content of an environment variable,
* directory and filename together
*
* params: dest..where to store result
* env...name of environment variable
* dir...directoryname
* fn....filename to append
*
* result: FALSE, if envvar could not be found or
* filename got too long
*/
BOOL link_envfname(EXPSTR * dest, STRPTR envname, STRPTR dir, STRPTR fn)
{
BOOL ok = FALSE;
STRPTR env = getenv(envname);
if (env)
{
STRPTR env1 = strclone(env); /* copy envvar to own memory area */
EXPSTR *tmpstr = init_estr(32);
/* strip linefeeds from hscenv */
while (strlen(env1) && (env1[strlen(env1)] == '\n'))
env1[strlen(env1)] = '\0';
if (dir)
{
link_fname(tmpstr, env1, dir);
}
else
{
set_estr(tmpstr, env1);
}
ok = link_fname(dest, estr2str(tmpstr), fn);
del_estr(tmpstr);
ufreestr(env1);
}
else
{
clr_estr(dest);
}
return ok;
}
/*
* tmpnamstr: alloc & create a string with a temp. filename
*
* result: string containig filename;
* MUST be release using ufreestr() by caller
* errors: return NULL; this can be because auf no more
* temp. files available or out of mem
*
* IMPORTANT: you need to copy the filename, if you
* call this function frquently
*/
static size_t adjust_prefixlen(size_t prefixlen)
{
#ifdef MSDOS
if (prefixlen > MAX_FNAME - 4)
prefixlen = MAX_FNAME - 4;
#else
if (prefixlen > MAX_FNAME - 8)
prefixlen = MAX_FNAME - 8;
#endif
return (prefixlen);
}
STRPTR tmpnamstr(STRPTR prefix)
{
STRARR buf[256 + 32];
LONG fileidx = 0;
STRPTR s = NULL;
FILE *file = NULL;
size_t prefixlen = 0;
if (prefix)
/* copy prefix to buffer */
prefixlen = adjust_prefixlen(strlen(prefix));
else
prefix = "";
/* copy prefix to buffer */
strcpy(buf, prefix);
/* add address of buffer to prefix */
sprintf(&(buf[strlen(prefix)]), "%p", tmpnamstr);
prefixlen = adjust_prefixlen(strlen(buf));
buf[prefixlen] = '\0';
/* try to open tmpfile for input until it fails */
do
{
fileidx++;
sprintf(&(buf[prefixlen]), "%04lx", fileidx);
strcat(buf, ".tmp");
file = fopen(buf, "r");
if (file)
{
if (fileidx == 0xffff)
fileidx = 0; /* ran out of names */
}
}
while (fileidx && file);
if (fileidx)
{
s = buf;
}
return (s);
}
/*
* get_relfname: get relative filename, according to given path
*
* params: absn..absolute filename
* curp..current path
*
* EXAMPLE:
* "image/back.gif" and "image/hugo/" -> "/back.gif"
* "image/back.gif" and "" -> "image/back.gif"
* "image/back.gif" and "people/" -> "/image/back.gif"
*/
BOOL get_relfname(EXPSTR * dest, STRPTR absn, STRPTR curp)
{
EXPSTR *fname = init_estr(32); /* file name only */
EXPSTR *abspa = init_estr(32); /* absolute path only */
EXPSTR *tmpp1 = init_estr(32); /* temp pointer */
EXPSTR *tmpp2 = init_estr(32);
STRPTR rest_absp = NULL; /* rest of current path */
STRPTR absp = NULL; /* path processing */
int cmp_result; /* stores result returned by upstrcmp */
/* init string array */
clr_estr(dest);
get_fname(fname, absn);
get_fpath(abspa, absn);
absp = estr2str(abspa);
/*
* skip all equal subdirs
*/
do
{
get_fsdir(tmpp1, absp);
get_fsdir(tmpp2, curp);
cmp_result = upstrcmp(estr2str(tmpp1), estr2str(tmpp2));
if (!cmp_result)
{
absp += estrlen(tmpp1);
curp += estrlen(tmpp2);
}
}
while (estrlen(tmpp1)
&& estrlen(tmpp2)
&& (!cmp_result));
/* remember equal part of path */
rest_absp = absp;
/*
* for every subdir in absp unequal to
* corresponding subdir curp, insert a parent dir
*/
if (curp[0])
do
{
get_fsdir(tmpp1, absp);
get_fsdir(tmpp2, curp);
cmp_result = upstrcmp(estr2str(tmpp1), estr2str(tmpp2));
if (cmp_result)
{
absp += estrlen(tmpp1);
curp += estrlen(tmpp2);
app_estr(dest, PARENT_DIR);
#if 0
printf("absp: (tmpp1) [%d] `%s'\n", estrlen(tmpp1), absp);
printf("curp: (tmpp2) [%d] `%s'\n", estrlen(tmpp2), curp);
printf("dest: `%s'\n", estr2str(dest));
#endif
}
}
while (strlen(curp) && cmp_result);
/* append equal part of path */
app_estr(dest, rest_absp);
/* append name of file */
app_estr(dest, estr2str(fname));
/* relaese resources */
del_estr(fname);
del_estr(abspa);
del_estr(tmpp1);
del_estr(tmpp2);
return (ok_fnl_fpath(dest));
}